#include <experimentPro.h>

extern QMap<QString,TcpClient*> clientList;
extern QMap<QString,SerialportClient*> serialPortClientList;

/**
 * @brief 构造函数
 */
ExperimentPro::ExperimentPro()
{

}

/**
 * @brief 析构函数
 */
ExperimentPro::~ExperimentPro()
{}
Q_INVOKABLE QVector<QVector<QPointF>> ExperimentPro::getChartInfo(QString equId,QString accessInfo,QString posInfo){
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);

    QString sql=QString("Select ExperimentGuid From EquipmentInfo Where Id='%1'").arg(equId);
    QString expId;


    query.exec(sql);
    while (query.next()) {
        expId=query.value("ExperimentGuid").toString();
    }
    QList<QString> posList=posInfo.split(',');

    QVector<QVector<QPointF>> result;

    for(int i=0;i<posList.length();i++){
        sql=QString("Select CyclesNumber,Case when s.%1=0 then 0 else f.%1 end as %1 "
                    "from sampleInfo s "
                    "join FluorescenceData f on s.ID=f.SampleId "
                    "join ItemCode i on f.positionNumber=i.code and i.DicCode='3' "
                    "where f.ExperimentGuid='%2' and i.Name ='%3'"
                    "ORDER BY CyclesNumber;").arg(accessInfo,expId,posList[i]);
        //        qDebug() << "查询数据点语句" << sql;
        query.exec(sql);

        QVector<QPointF> info;
        while (query.next()) {
            info.push_back(QPointF(query.value("CyclesNumber").toDouble(), query.value(accessInfo).toDouble()));
        }
        result.append(info);
    }

    return  result;
}

Q_INVOKABLE QMap<QString, QVariantList> ExperimentPro::getBarChartInfo(QString equId,QString accessInfo,QString posInfo){
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);

    QString sql=QString("Select ExperimentGuid From EquipmentInfo Where Id='%1'").arg(equId);
    QString expId;
    query.exec(sql);
    while (query.next()) {
        expId=query.value("ExperimentGuid").toString();
    }
    QList<QString> posList=posInfo.split(',');

    QString newPos;
    for(int i=0;i<posList.length();i++){
        newPos+=QString("'%1',").arg(posList[i]);
    }
    newPos = newPos.left(newPos.length()-1);

    QString newAccess;
    QList<QString> accessList=accessInfo.split(',');
    for(int i=0;i<accessList.length();i++){
        newAccess+=QString("Case when s.%1=0 then 0 else f.%1 end as %1,").arg(accessList[i]);
    }
    newAccess = newAccess.left(newAccess.length()-1);

    int currentCycle=0;
    if(clientList.contains(equId))
    {
        currentCycle = clientList[equId]->cycle.toInt();
    }
    else if(serialPortClientList.contains(equId))
    {
        currentCycle = serialPortClientList[equId]->cycle.toInt();
    }


    sql=QString("Select distinct i.Name as PositionNumber,%1 "
                "from sampleInfo s "
                "join FluorescenceData f on s.ID=f.SampleId "
                "join ItemCode i on f.positionNumber=i.code and i.DicCode='3' "
                "where f.ExperimentGuid='%2' and i.Name in (%3) and CyclesNumber='%4' "
                "ORDER BY PositionNumber;").arg(newAccess,expId,newPos,QString::number(currentCycle-1));
    query.exec(sql);
    QVariantList pos;
    QVariantList fam;
    QVariantList vic;
    QVariantList rox;
    QVariantList cy5;

    while (query.next()) {
        pos.push_back(query.value("PositionNumber").toString());
        fam.push_back(query.value("FAM").toInt());
        vic.push_back(query.value("VIC").toInt());
        rox.push_back(query.value("ROX").toInt());
        cy5.push_back(query.value("CY5").toInt());
    }

    QMap<QString, QVariantList> map;


    if(pos.size() == 0){
        foreach(QString posi, posList){
            if(posi==""){
                posi = "未选择孔位";
            }
            pos.append(posi);
            fam.append(0);
            vic.append(0);
            rox.append(0);
            cy5.append(0);
        }
    }

    map["posi"] = pos;
    map["FAM"] = fam;
    map["VIC"] = vic;
    map["ROX"] = rox;
    map["CY5"] = cy5;

    return  map;
}

Q_INVOKABLE QVariantMap ExperimentPro::getOtherInfo(QString equId)
{
    QVariantMap map;

    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select ExperimentGuid From EquipmentInfo Where id='%1'").arg(equId);
    query.exec(sql);
    QString expGuid;
    while (query.next()) {
        expGuid=query.value("ExperimentGuid").toString();
    }

    sql=QString("Select CycleNum from AmplStepPro where  ExperimentGuid='%1'  and "
                "CASE WHEN "
                "(Select count(*) from AmplStepPro where  IsCollect='是' and ExperimentGuid='%1')>0 "
                "then "
                "IsCollect='是' "
                "else "
                "StepNum=(Select StepNum from AmplStepPro where ExperimentGuid='%1' and CycleNumber<>0) "
                "end").arg(expGuid);
    query.exec(sql);
    while (query.next()) {
        map["CycleNum"]=query.value("CycleNum").toString();
    }

    sql=QString("Select e.RunTime,Duration From ExperimentInfo e "
                "Join AmplProgramPro a on e.Id=a.ExperimentGuid "
                "Where e.Id='%1'").arg(expGuid);
    query.exec(sql);

    while (query.next()) {
        map["RunTime"]=query.value("RunTime").toString();
        map["Duration"]=query.value("Duration").toString();
    }
    if(clientList.contains(equId))
    {
        map["Step"] = clientList[equId]->step;
        map["Temp"] = clientList[equId]->temp;
        map["Cycle"] = clientList[equId]->cycle;

        map["ChartStatus"]=clientList[equId]->chartStatus;//0正常 1:刷图表数据
        map["ExpStatus"]=clientList[equId]->experimentStatus; //1运行 2 完成
        clientList[equId]->chartStatus="0";
    }
    else if(serialPortClientList.contains(equId))
    {
        map["Step"] = serialPortClientList[equId]->step;
        map["Temp"] = serialPortClientList[equId]->temp;
        map["Cycle"] = serialPortClientList[equId]->cycle;

        map["ChartStatus"]=serialPortClientList[equId]->chartStatus;//0正常 1:刷图表数据
        map["ExpStatus"]=serialPortClientList[equId]->experimentStatus; //1运行 2 完成
        serialPortClientList[equId]->chartStatus="0";
    }

    return  map;
}

Q_INVOKABLE void ExperimentPro::stopExperiment(QString equId){
    QString data=" 00 00 00 01 00 04 ";
    QString finalData=QString(" %1 %2 55 AA ").arg(data,common->GetCrcCheck(data.toLatin1()));
    QString dataLength=common->TenToSixteen(finalData.remove(QRegExp("\\s")).length()/2,4);
    QString head= QString("62 00 00 3A %1 ").arg(dataLength);
    QString result=head+finalData;
    QByteArray sendInfo=common->GetSendData(result);
    if(clientList.contains(equId)){
        clientList[equId]->ClientSendingData(sendInfo);

        clientList[equId]->experimentStatus=2;
    }
    else if(serialPortClientList.contains(equId)){
        serialPortClientList[equId]->ClientSendingData(sendInfo);
        serialPortClientList[equId]->experimentStatus=2;
    }

    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql= QString("Update EquipmentInfo set EquStatus='3' where id='%2'").arg(equId);
    bool res = query.exec(sql);
    LogHelperJ::write(sql + (res?"[true]":"[false]"));


    QString finishTime= common->GetDateTimeStr();
    sql= QString("Update ExperimentInfo set Status='完成',FinishTime='%1' where id=(Select ExperimentGuid From EquipmentInfo Where Id='%2')").arg(finishTime, equId);
    query.exec(sql);

    WlkOperator *wlk=new WlkOperator();
    wlk->SaveResultInfo(equId);

    SaveExpInfo* sei = new SaveExpInfo();       // 导出报告 + 实验历史数据存储
    sei->calculate(equId);

}

Q_INVOKABLE int ExperimentPro::checkIsCollect(QString equId)
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select ExperimentGuid From EquipmentInfo Where id='%1'").arg(equId);
    query.exec(sql);
    QString expGuid;
    while (query.next()) {
        expGuid=query.value("ExperimentGuid").toString();
    }
    int result;
    sql=QString("Select count(*) as Num from AmplStepPro where IsCollect='是' and ExperimentGuid='%1'").arg(expGuid);
    query.exec(sql);
    while (query.next()) {
        result=query.value("Num").toInt();
    }
    return  result;
}

Q_INVOKABLE QVariantMap ExperimentPro::getAllTempInfo(QString equId)
{
    QVariantMap map;
    if(clientList.contains(equId)){
        map["TempOne"]=clientList[equId]->temp;
        map["TempTwo"]=clientList[equId]->tempTwo;
        map["TempThree"]=clientList[equId]->tempThree;
        map["TempFour"]=clientList[equId]->tempFour;
        map["TempFive"]=clientList[equId]->tempFive;
        map["TempSix"]=clientList[equId]->tempSix;
    }
    else if(serialPortClientList.contains(equId)){
        map["TempOne"]=serialPortClientList[equId]->temp;
        map["TempTwo"]=serialPortClientList[equId]->tempTwo;
        map["TempThree"]=serialPortClientList[equId]->tempThree;
        map["TempFour"]=serialPortClientList[equId]->tempFour;
        map["TempFive"]=serialPortClientList[equId]->tempFive;
        map["TempSix"]=serialPortClientList[equId]->tempSix;
    }

    return  map;
}

Q_INVOKABLE QVariantMap ExperimentPro::getAmplInfo(QString equId){
    qDebug() << __FUNCTION__ << equId;
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QVariantMap map;
    QString sql=QString("Select Id,ProgramName,Duration,StepNum,HotCoverStatus,HotCoverTemp,CreateDate,Memo From AmplProgramPro Where ExperimentGuid=(Select ExperimentGuid From EquipmentInfo Where id='%1')").arg(equId);

    query.exec(sql);
    while (query.next()) {
        for (int i = 0; i < query.record().count(); ++i) {
            map[query.record().fieldName(i)] = query.value(i);
        }
    }
    qDebug() << map;
    return  map;
}

Q_INVOKABLE QVariantList ExperimentPro::getAmplStep(QString equId){
    qDebug() << __FUNCTION__ << equId;
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select Id,ProgramId,StepNum,Temperature,ExecutionTime,Rate,IsCollect,CycleNumber,CycleNum From AmplStepPro Where ExperimentGuid=(Select ExperimentGuid From EquipmentInfo Where id='%1')").arg(equId);

    query.exec(sql);
    QVariantList result;
    while (query.next()) {
        QVariantMap map;

        for (int i = 0; i < query.record().count(); ++i) {
            map[query.record().fieldName(i)] = query.value(i);
        }
        result.append(map);
    }
    qDebug() << result;
    return  result;
}

Q_INVOKABLE QString ExperimentPro::getExperimentErrorMsg(QString equId)
{
    if(clientList.contains(equId)){
        return  clientList[equId]->allerror;

    }else if(serialPortClientList.contains(equId)){
        return  serialPortClientList[equId]->allerror;

    }
}
